#include "imicodecffmpegapi.h"
#include "imicodecffmpegapi_impl.h"
#include "log.h"
using namespace imimediacore_namespace;

handleMap<imicodecffmpegapi_impl> _HandleMap(1000);
std::list<imicodecffmpegapi_impl*> _HandleList;

CDEOCFFMPEG_LIB int IMICodecFFmpeg_Init(IMICodecFFmpegHandle* pIMIhandle)
{
	imicodecffmpegapi_impl* impl = new imicodecffmpegapi_impl;
	int r = impl->init();
	if (r == 0)
	{
		*pIMIhandle = _HandleMap.getMap(impl);
		_HandleList.push_back(impl);
	}
	else
	{
		delete impl;
		*pIMIhandle = 0;
	}
	LOGE("IMICodecFFmpeg_Init IMICodecFFmpegHandle = %d\n", *pIMIhandle);
	return r;
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_SelectDecoder(IMICodecFFmpegHandle IMIhandle, int iCodecType, int iFlag)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->setdecoder(iCodecType);
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_Fini(IMICodecFFmpegHandle IMIhandle)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	int r = impl->fini();
	std::list<imicodecffmpegapi_impl*>::iterator it = _HandleList.begin();
	std::list<imicodecffmpegapi_impl*>::iterator itnext;
	while (it != _HandleList.end())
	{
		itnext = it;
		++itnext;
		if((*it) == impl)
		{
			//(*it)->Release();
			delete (*it);
			_HandleList.erase(it);
		}
		it = itnext;
	}
	_HandleMap.release(IMIhandle);
	LOGE("IMICodecFFmpeg_Fini IMICodecFFmpegHandle = %d\n", IMIhandle);
	return r;
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_Decode(IMICodecFFmpegHandle IMIhandle, unsigned char* pData, int iDataLen, unsigned long long ullPTS)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->decode(pData, iDataLen);
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_GetWidth(IMICodecFFmpegHandle IMIhandle)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->width();
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_GetHeight(IMICodecFFmpegHandle IMIhandle)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->height();
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_ToTexture(IMICodecFFmpegHandle IMIhandle, int iY, int iU, int iV)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->totexture(iY, iU, iV);
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_GetYUVData(IMICodecFFmpegHandle IMIhandle, unsigned char* pY, unsigned char* pU, unsigned char* pV)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->yuvdata(pY, pU, pV);
}

CDEOCFFMPEG_LIB int IMICodecFFmpeg_GetJpegData(IMICodecFFmpegHandle IMIhandle, unsigned char* pY, unsigned char* pU, unsigned char* pV, unsigned char* pBuffer, int width, int height, int quality)
{
	imicodecffmpegapi_impl* impl = (imicodecffmpegapi_impl*)_HandleMap.getSomthing(IMIhandle);
	if (impl == 0) return imi_retcode_para;
	return impl->jpegdata(pY, pU, pV, pBuffer, width, height, quality);
}